# AI智能化功能模型
from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone
import json
from decimal import Decimal

from .models import Asset, AssetCategory, Department, MaintenanceRecord


class AssetRecommendation(models.Model):
    """资产推荐模型"""
    RECOMMENDATION_TYPE_CHOICES = [
        ('maintenance', '维修推荐'),
        ('replacement', '更换推荐'),
        ('optimization', '优化推荐'),
        ('allocation', '分配推荐'),
        ('procurement', '采购推荐'),
    ]
    
    PRIORITY_CHOICES = [
        ('low', '低'),
        ('medium', '中'),
        ('high', '高'),
        ('urgent', '紧急'),
    ]
    
    user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="用户")
    recommendation_type = models.CharField(max_length=20, choices=RECOMMENDATION_TYPE_CHOICES, verbose_name="推荐类型")
    title = models.CharField(max_length=200, verbose_name="推荐标题")
    description = models.TextField(verbose_name="推荐描述")
    
    # 关联资产
    asset = models.ForeignKey(Asset, on_delete=models.CASCADE, null=True, blank=True, verbose_name="关联资产")
    category = models.ForeignKey(AssetCategory, on_delete=models.CASCADE, null=True, blank=True, verbose_name="关联类别")
    department = models.ForeignKey(Department, on_delete=models.CASCADE, null=True, blank=True, verbose_name="关联部门")
    
    # 推荐详情
    recommendation_data = models.JSONField(default=dict, verbose_name="推荐数据")
    confidence_score = models.FloatField(default=0.0, verbose_name="置信度分数")
    priority = models.CharField(max_length=10, choices=PRIORITY_CHOICES, default='medium', verbose_name="优先级")
    
    # 状态信息
    is_read = models.BooleanField(default=False, verbose_name="是否已读")
    is_accepted = models.BooleanField(default=False, verbose_name="是否已接受")
    is_dismissed = models.BooleanField(default=False, verbose_name="是否已忽略")
    
    # 时间信息
    expires_at = models.DateTimeField(null=True, blank=True, verbose_name="过期时间")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")
    
    class Meta:
        verbose_name = "资产推荐"
        verbose_name_plural = "资产推荐"
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['user', 'is_read', '-created_at']),
            models.Index(fields=['recommendation_type', '-created_at']),
        ]
    
    def __str__(self):
        return f"{self.title} - {self.user.username}"
    
    def mark_as_read(self):
        """标记为已读"""
        self.is_read = True
        self.save(update_fields=['is_read'])
    
    def accept(self):
        """接受推荐"""
        self.is_accepted = True
        self.is_read = True
        self.save(update_fields=['is_accepted', 'is_read'])
    
    def dismiss(self):
        """忽略推荐"""
        self.is_dismissed = True
        self.is_read = True
        self.save(update_fields=['is_dismissed', 'is_read'])
    
    @property
    def is_expired(self):
        """判断是否已过期"""
        if self.expires_at:
            return timezone.now() > self.expires_at
        return False


class AssetAnomalyDetection(models.Model):
    """资产异常检测模型"""
    ANOMALY_TYPE_CHOICES = [
        ('usage_pattern', '使用模式异常'),
        ('maintenance_frequency', '维修频率异常'),
        ('cost_anomaly', '成本异常'),
        ('location_anomaly', '位置异常'),
        ('status_anomaly', '状态异常'),
        ('performance_degradation', '性能下降'),
    ]
    
    SEVERITY_CHOICES = [
        ('low', '低'),
        ('medium', '中'),
        ('high', '高'),
        ('critical', '严重'),
    ]
    
    asset = models.ForeignKey(Asset, on_delete=models.CASCADE, verbose_name="资产", related_name='anomaly_detections')
    anomaly_type = models.CharField(max_length=30, choices=ANOMALY_TYPE_CHOICES, verbose_name="异常类型")
    severity = models.CharField(max_length=10, choices=SEVERITY_CHOICES, verbose_name="严重程度")
    
    # 异常详情
    description = models.TextField(verbose_name="异常描述")
    anomaly_data = models.JSONField(default=dict, verbose_name="异常数据")
    confidence_score = models.FloatField(verbose_name="置信度")
    
    # 检测信息
    detection_algorithm = models.CharField(max_length=100, verbose_name="检测算法")
    detection_parameters = models.JSONField(default=dict, verbose_name="检测参数")
    
    # 处理状态
    is_confirmed = models.BooleanField(default=False, verbose_name="是否已确认")
    is_resolved = models.BooleanField(default=False, verbose_name="是否已解决")
    resolution_notes = models.TextField(blank=True, verbose_name="解决备注")
    
    # 时间信息
    detected_at = models.DateTimeField(auto_now_add=True, verbose_name="检测时间")
    confirmed_at = models.DateTimeField(null=True, blank=True, verbose_name="确认时间")
    resolved_at = models.DateTimeField(null=True, blank=True, verbose_name="解决时间")
    
    class Meta:
        verbose_name = "资产异常检测"
        verbose_name_plural = "资产异常检测"
        ordering = ['-detected_at']
        indexes = [
            models.Index(fields=['asset', '-detected_at']),
            models.Index(fields=['anomaly_type', 'severity']),
        ]
    
    def __str__(self):
        return f"{self.asset.asset_number} - {self.get_anomaly_type_display()}"
    
    def confirm(self, user, notes=''):
        """确认异常"""
        self.is_confirmed = True
        self.confirmed_at = timezone.now()
        self.resolution_notes = notes
        self.save()
        
        # 创建推荐
        self._create_recommendation(user)
    
    def resolve(self, user, notes=''):
        """解决异常"""
        self.is_resolved = True
        self.resolved_at = timezone.now()
        self.resolution_notes = notes
        self.save()
    
    def _create_recommendation(self, user):
        """基于异常创建推荐"""
        if self.anomaly_type == 'maintenance_frequency':
            AssetRecommendation.objects.create(
                user=user,
                recommendation_type='maintenance',
                title=f'建议对资产 {self.asset.asset_number} 进行预防性维修',
                description=f'检测到该资产维修频率异常，建议进行预防性维修以避免更大损失。',
                asset=self.asset,
                confidence_score=self.confidence_score,
                priority='high' if self.severity in ['high', 'critical'] else 'medium'
            )
        elif self.anomaly_type == 'performance_degradation':
            AssetRecommendation.objects.create(
                user=user,
                recommendation_type='replacement',
                title=f'建议考虑更换资产 {self.asset.asset_number}',
                description=f'检测到该资产性能持续下降，建议评估是否需要更换。',
                asset=self.asset,
                confidence_score=self.confidence_score,
                priority='medium'
            )


class PredictiveMaintenanceModel(models.Model):
    """预测性维护模型"""
    MODEL_TYPE_CHOICES = [
        ('time_based', '基于时间'),
        ('usage_based', '基于使用量'),
        ('condition_based', '基于状态'),
        ('ml_based', '机器学习'),
    ]
    
    name = models.CharField(max_length=200, verbose_name="模型名称")
    model_type = models.CharField(max_length=20, choices=MODEL_TYPE_CHOICES, verbose_name="模型类型")
    category = models.ForeignKey(AssetCategory, on_delete=models.CASCADE, verbose_name="适用类别")
    
    # 模型参数
    model_parameters = models.JSONField(default=dict, verbose_name="模型参数")
    training_data = models.JSONField(default=dict, verbose_name="训练数据")
    
    # 性能指标
    accuracy = models.FloatField(default=0.0, verbose_name="准确率")
    precision = models.FloatField(default=0.0, verbose_name="精确率")
    recall = models.FloatField(default=0.0, verbose_name="召回率")
    f1_score = models.FloatField(default=0.0, verbose_name="F1分数")
    
    # 状态信息
    is_active = models.BooleanField(default=True, verbose_name="是否启用")
    last_trained_at = models.DateTimeField(null=True, blank=True, verbose_name="最后训练时间")
    
    created_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, verbose_name="创建人")
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")
    
    class Meta:
        verbose_name = "预测性维护模型"
        verbose_name_plural = "预测性维护模型"
        ordering = ['-created_at']
    
    def __str__(self):
        return f"{self.name} - {self.category.name}"
    
    def predict_maintenance_date(self, asset):
        """预测维护日期"""
        if not self.is_active:
            return None
        
        # 根据模型类型进行预测
        if self.model_type == 'time_based':
            return self._predict_time_based(asset)
        elif self.model_type == 'usage_based':
            return self._predict_usage_based(asset)
        elif self.model_type == 'condition_based':
            return self._predict_condition_based(asset)
        elif self.model_type == 'ml_based':
            return self._predict_ml_based(asset)
        
        return None
    
    def _predict_time_based(self, asset):
        """基于时间的预测"""
        from datetime import timedelta
        
        # 获取平均维修间隔
        avg_interval = self.model_parameters.get('avg_maintenance_interval', 365)  # 默认365天
        
        # 获取最后一次维修时间
        last_maintenance = asset.maintenance_records.filter(
            status='completed'
        ).order_by('-completed_at').first()
        
        if last_maintenance:
            return last_maintenance.completed_at + timedelta(days=avg_interval)
        else:
            # 如果没有维修记录，从购买日期开始计算
            return asset.purchase_date + timedelta(days=avg_interval)
    
    def _predict_usage_based(self, asset):
        """基于使用量的预测"""
        # 这里需要根据资产的使用数据进行预测
        # 暂时返回None，实际实现需要更复杂的逻辑
        return None
    
    def _predict_condition_based(self, asset):
        """基于状态的预测"""
        # 这里需要根据资产的状态数据进行预测
        # 暂时返回None，实际实现需要传感器数据等
        return None
    
    def _predict_ml_based(self, asset):
        """基于机器学习的预测"""
        # 这里需要调用训练好的机器学习模型
        # 暂时返回None，实际实现需要集成ML框架
        return None


class AssetUtilizationAnalysis(models.Model):
    """资产利用率分析模型"""
    asset = models.ForeignKey(Asset, on_delete=models.CASCADE, verbose_name="资产", related_name='utilization_analyses')
    analysis_period_start = models.DateTimeField(verbose_name="分析期间开始")
    analysis_period_end = models.DateTimeField(verbose_name="分析期间结束")
    
    # 利用率指标
    utilization_rate = models.FloatField(verbose_name="利用率(%)")
    idle_time_hours = models.FloatField(verbose_name="闲置时间(小时)")
    active_time_hours = models.FloatField(verbose_name="活跃时间(小时)")
    maintenance_time_hours = models.FloatField(default=0, verbose_name="维修时间(小时)")
    
    # 分析数据
    analysis_data = models.JSONField(default=dict, verbose_name="分析数据")
    
    # 建议
    optimization_suggestions = models.TextField(blank=True, verbose_name="优化建议")
    
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    
    class Meta:
        verbose_name = "资产利用率分析"
        verbose_name_plural = "资产利用率分析"
        ordering = ['-created_at']
        unique_together = ['asset', 'analysis_period_start', 'analysis_period_end']
    
    def __str__(self):
        return f"{self.asset.asset_number} - {self.utilization_rate:.1f}%"
    
    @property
    def total_hours(self):
        """总时间"""
        duration = self.analysis_period_end - self.analysis_period_start
        return duration.total_seconds() / 3600
    
    @property
    def efficiency_score(self):
        """效率评分"""
        if self.utilization_rate >= 80:
            return 'excellent'
        elif self.utilization_rate >= 60:
            return 'good'
        elif self.utilization_rate >= 40:
            return 'fair'
        else:
            return 'poor'
    
    def generate_suggestions(self):
        """生成优化建议"""
        suggestions = []
        
        if self.utilization_rate < 40:
            suggestions.append("资产利用率较低，建议考虑重新分配或共享使用")
        
        if self.idle_time_hours > self.total_hours * 0.5:
            suggestions.append("闲置时间过长，建议优化资产配置")
        
        if self.maintenance_time_hours > self.total_hours * 0.2:
            suggestions.append("维修时间占比过高，建议加强预防性维护")
        
        self.optimization_suggestions = "; ".join(suggestions)
        self.save(update_fields=['optimization_suggestions'])


class SmartReport(models.Model):
    """智能报表模型"""
    REPORT_TYPE_CHOICES = [
        ('asset_summary', '资产汇总'),
        ('utilization_analysis', '利用率分析'),
        ('maintenance_forecast', '维修预测'),
        ('cost_analysis', '成本分析'),
        ('anomaly_report', '异常报告'),
        ('recommendation_summary', '推荐汇总'),
    ]
    
    name = models.CharField(max_length=200, verbose_name="报表名称")
    report_type = models.CharField(max_length=30, choices=REPORT_TYPE_CHOICES, verbose_name="报表类型")
    description = models.TextField(blank=True, verbose_name="报表描述")
    
    # 报表配置
    report_config = models.JSONField(default=dict, verbose_name="报表配置")
    
    # 生成的报表数据
    report_data = models.JSONField(default=dict, verbose_name="报表数据")
    insights = models.TextField(blank=True, verbose_name="智能洞察")
    
    # 状态信息
    is_scheduled = models.BooleanField(default=False, verbose_name="是否定期生成")
    schedule_config = models.JSONField(default=dict, verbose_name="调度配置")
    
    generated_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, verbose_name="生成人")
    generated_at = models.DateTimeField(auto_now_add=True, verbose_name="生成时间")
    
    class Meta:
        verbose_name = "智能报表"
        verbose_name_plural = "智能报表"
        ordering = ['-generated_at']
    
    def __str__(self):
        return f"{self.name} - {self.generated_at.strftime('%Y-%m-%d')}"
    
    def generate_insights(self):
        """生成智能洞察"""
        insights = []
        
        if self.report_type == 'asset_summary':
            insights = self._generate_asset_summary_insights()
        elif self.report_type == 'utilization_analysis':
            insights = self._generate_utilization_insights()
        elif self.report_type == 'maintenance_forecast':
            insights = self._generate_maintenance_insights()
        
        self.insights = "\n".join(insights)
        self.save(update_fields=['insights'])
    
    def _generate_asset_summary_insights(self):
        """生成资产汇总洞察"""
        insights = []
        data = self.report_data
        
        if 'total_assets' in data:
            insights.append(f"当前共有 {data['total_assets']} 项资产")
        
        if 'idle_assets' in data and data['idle_assets'] > 0:
            insights.append(f"发现 {data['idle_assets']} 项闲置资产，建议优化配置")
        
        return insights
    
    def _generate_utilization_insights(self):
        """生成利用率洞察"""
        insights = []
        # 实现利用率分析洞察逻辑
        return insights
    
    def _generate_maintenance_insights(self):
        """生成维修预测洞察"""
        insights = []
        # 实现维修预测洞察逻辑
        return insights